<template>
  <div class="cascader-batch-edit">
    <div class="edit-container">
      <!-- 级联选择器编辑区域 -->
      <div class="level-container">
        <div
          v-for="(level, index) in levels"
          :key="index"
          class="level-column"
        >
          <div class="level-header">
            <span>{{ getLevelTitle(index + 1) }}</span>
            <el-button
              v-if="index < 4"
              link
              type="primary"
              @click="addOption(index)"
            >
              <el-icon>
                <ele-Plus />
              </el-icon>
              {{ $t("formgen.option.addOption") }}
            </el-button>
          </div>
          <div class="options-list">
            <div
              v-for="item in level"
              :key="item.value"
              :class="['option-item', { active: isActive(item, index) }]"
              @click="selectOption(item, index)"
            >
              <div class="option-content">
                <el-input
                  v-if="item.editing"
                  v-model="item.label"
                  v-focus
                  size="small"
                  @blur="finishEdit(item)"
                  @keyup.enter="finishEdit(item)"
                />
                <span
                  v-else
                  class="option-label"
                  @dblclick="startEdit(item)"
                >
                  {{ item.label }}
                </span>
              </div>
              <div class="option-actions">
                <el-icon
                  v-if="index < 3"
                  class="action-icon add-icon"
                  size="20"
                  @click.stop="addChild(item, index)"
                >
                  <ele-Plus />
                </el-icon>
                <el-icon
                  class="action-icon delete-icon"
                  size="20"
                  @click.stop="deleteOption(item, index)"
                >
                  <ele-Delete />
                </el-icon>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>

    <!-- 底部按钮 -->
    <div class="dialog-footer">
      <el-button
        size="default"
        @click="$emit('cancel')"
      >
        {{ $t("formI18n.all.cancel") }}
      </el-button>
      <el-button
        size="default"
        type="primary"
        @click="handleConfirm"
      >
        {{ $t("formI18n.all.confirm") }}
      </el-button>
    </div>
  </div>
</template>

<script lang="ts" setup>
import { computed, ref, watch } from "vue";
import { generateId } from "@/utils";
import { cloneDeep } from "lodash-es";

// 自定义指令：自动聚焦
const vFocus = {
  mounted: (el: HTMLElement) => {
    const input = el.querySelector("input");
    if (input) {
      input.focus();
    }
  }
};

interface TreeNode {
  id: string | number;
  value: string;
  label: string;
  level: number;
  children?: TreeNode[];
  editing?: boolean;
}

const props = defineProps<{
  treeData: TreeNode[];
}>();

const emit = defineEmits<{
  (e: "close", data: TreeNode[]): void;
  (e: "cancel"): void;
}>();

// 本地数据副本
const localTreeData = ref<TreeNode[]>(cloneDeep(props.treeData));

// 当前选中的选项路径
const selectedPath = ref<TreeNode[]>([]);
// 当前编辑的级别（1-4）
const currentLevel = ref(1);

// 根据级别获取标题
const getLevelTitle = (level: number) => {
  return `${level}级选项`;
};

// 计算每一级的选项列表
const levels = computed(() => {
  const result: TreeNode[][] = [];

  // 第一级使用本地数据
  result[0] = localTreeData.value;

  // 始终显示四列，如果没有数据则显示空数组
  for (let i = 1; i < 4; i++) {
    result[i] = selectedPath.value[i - 1]?.children || [];
  }

  return result;
});

// 判断选项是否被选中
const isActive = (item: TreeNode, level: number) => {
  return selectedPath.value[level]?.value === item.value;
};

// 选择选项
const selectOption = (item: TreeNode, level: number) => {
  // 清除当前级别之后的选择
  selectedPath.value = selectedPath.value.slice(0, level);
  selectedPath.value.push(item);
};

// 开始编辑选项
const startEdit = (item: TreeNode) => {
  item.editing = true;
};

// 完成编辑
const finishEdit = (item: TreeNode) => {
  item.editing = false;
  if (!item.label.trim()) {
    item.label = "未命名选项";
  }
};

// 添加选项
const addOption = (level: number) => {
  const newNode: TreeNode = {
    id: generateId(),
    value: generateId(),
    label: "新选项",
    level: level + 1,
    editing: true
  };

  if (level === 0) {
    localTreeData.value.push(newNode);
  } else {
    const parent = selectedPath.value[level - 1];
    if (!parent.children) {
      parent.children = [];
    }
    parent.children.push(newNode);
  }
};

// 添加子选项
const addChild = (item: TreeNode, level: number) => {
  if (level >= 3) return; // 最多4级
  if (!item.children) {
    item.children = [];
  }
  const newNode: TreeNode = {
    id: generateId(),
    value: generateId(),
    label: "新选项",
    level: level + 2,
    editing: true
  };
  item.children.push(newNode);
  selectOption(item, level);
};

// 删除选项
const deleteOption = (item: TreeNode, level: number) => {
  if (level === 0) {
    const index = localTreeData.value.findIndex(node => node.value === item.value);
    if (index !== -1) {
      localTreeData.value.splice(index, 1);
    }
  } else {
    const parent = selectedPath.value[level - 1];
    if (parent.children) {
      const index = parent.children.findIndex(node => node.value === item.value);
      if (index !== -1) {
        parent.children.splice(index, 1);
      }
    }
  }
  // 如果删除的是选中的节点，清除选择路径
  if (selectedPath.value[level]?.value === item.value) {
    selectedPath.value = selectedPath.value.slice(0, level);
    currentLevel.value = level + 1;
  }
};

// 确认修改
const handleConfirm = () => {
  emit("close", cloneDeep(localTreeData.value));
};

// 监听原始数据变化
watch(
  () => props.treeData,
  () => {
    localTreeData.value = cloneDeep(props.treeData);
    selectedPath.value = [];
  },
  { deep: true }
);
</script>

<style lang="scss" scoped>
.cascader-batch-edit {
  padding: 20px;
  user-select: none; // 禁止文字选中

  .edit-container {
    height: 500px;
    border: 1px solid var(--el-border-color-lighter);
    border-radius: 4px;
    padding: 16px;
    overflow-x: auto;
  }

  .level-container {
    display: flex;
    gap: 16px;
    height: 100%;
    min-width: fit-content;
  }

  .level-column {
    width: 220px;
    flex: none;
    display: flex;
    flex-direction: column;
    height: 100%;
    position: relative;

    &:not(:last-child)::after {
      content: "";
      position: absolute;
      right: -8px;
      top: 0;
      bottom: 0;
      width: 1px;
      background-color: var(--el-border-color-lighter);
    }
  }

  .level-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 12px;
    padding: 0 8px;
    flex-shrink: 0;

    span {
      font-weight: 500;
      color: var(--el-text-color-primary);
    }
  }

  .options-list {
    display: flex;
    flex-direction: column;
    gap: 8px;
    overflow-y: auto;
    flex: 1;
    padding-right: 8px;

    &::-webkit-scrollbar {
      width: 6px;
    }

    &::-webkit-scrollbar-thumb {
      background-color: var(--el-border-color);
      border-radius: 3px;
    }

    &::-webkit-scrollbar-track {
      background-color: var(--el-fill-color-lighter);
      border-radius: 3px;
    }
  }

  .option-item {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 8px 12px;
    border-radius: 4px;
    border: 1px solid var(--el-border-color-lighter);
    cursor: pointer;
    transition: all 0.3s;

    &:hover {
      border-color: var(--el-border-color);
      background-color: var(--el-fill-color-light);

      .option-actions {
        opacity: 1;
      }
    }

    &.active {
      border-color: var(--el-color-primary);
      background-color: var(--el-color-primary-light-9);
    }
  }

  .option-content {
    flex: 1;
    margin-right: 8px;
  }

  .option-label {
    display: block;
    width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  .option-actions {
    display: flex;
    gap: 12px;
    opacity: 0;
    transition: opacity 0.3s;

    .action-icon {
      cursor: pointer;
      padding: 4px;
      border-radius: 4px;
      font-size: 18px;
      transition: all 0.3s;

      &.add-icon {
        color: var(--el-color-primary);

        &:hover {
          background-color: var(--el-color-primary-light-9);
        }
      }

      &.delete-icon {
        color: var(--el-color-danger);

        &:hover {
          background-color: var(--el-color-danger-light-9);
        }
      }
    }
  }

  .dialog-footer {
    margin-top: 20px;
    text-align: right;
  }
}
</style>
